#include <config.h>
#include <string.h>
#include <math.h>
#include <ft2build.h>
#include <freetype/ftglyph.h>
#include <freetype.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H

typedef struct freetype_st
{
  FT_Library    library;
  FT_Face       face;

  FT_GlyphSlot  slot;
  FT_Matrix     matrix;
  FT_Vector     pen;
  FT_Error      error;
  FT_Glyph      glyph;

  char*         filename;
  double        angle;
}T_freetype, *PT_freetype;

static void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y, int frontcolor, int backcolor)
{
	FT_Int  i, j, p, q;
	FT_Int  x_max = x + bitmap->width;
	FT_Int  y_max = y + bitmap->rows;

	for ( i = x, p = 0; i < x_max; i++, p++ )
	{
		for ( j = y, q = 0; j < y_max; j++, q++ )
		{
			if ( i < 0|| j < 0|| i >= LCDWIDTH ||j >= LCDHEIGHT)
			{
				continue;
			}
			if(bitmap->buffer[q * bitmap->width + p])
				g_ptDisplayDevice->displayShowPixel(i,j,frontcolor);
			else
				g_ptDisplayDevice->displayShowPixel(i,j,backcolor);
		}
	}
}

static int numberOfOneBits(unsigned char code)
{
	int i;
	int count=0;

	for(i=0;i<=7;i++)
	{
		if(code & 0x80)
			count++;
		else
			break;
		code = code<<1;
	}

	return count;
}

static int utf8GetCodeFromBuff(unsigned char *Start, unsigned char *End, unsigned int *code)
{
	int ret,i;
	unsigned char *buff = Start;
	unsigned char temp;
	unsigned int codebuff =0;

	ret = numberOfOneBits(buff[0]);

	if((buff>=End)||((buff+ret) >End))
		return 0;

	if(ret ==0)
	{
		*code = buff[0];
		return 1;
	}
	else
	{
		temp = buff[0];
		temp = temp<<ret;
		temp = temp>>ret;
		codebuff = temp;

		for(i=1;i<ret;i++)
		{
			temp = buff[i]&0x3f;
			codebuff = (codebuff<<6)+temp;
		}
		*code = codebuff;

		return ret;
	}

	return 0;
}

static int getCodeFromChar(char *str,unsigned int *data,int Maxlenth)
{
	int ret;
	int i=0;
	int count=0;
	int lenth = strlen(str);

	while(count <lenth)
	{
		ret = utf8GetCodeFromBuff((unsigned char*)str,(unsigned char*)str+lenth,&data[i]);
		str  +=ret;
		count+=ret;
		i++;
		if(i>=Maxlenth) break;
	}
	
	return i;
}

int freetypeShowStr(int x, int y, int fontSize, int showLenth, char *str, int frontcolor, int backcolor)
{
	int lenth;
	T_freetype freetype;
	unsigned int code[FONTCODESIZE];

	if(showLenth<=0 || str ==NULL)
		return -1;

	lenth = getCodeFromChar(str, code, FONTCODESIZE);
	if(lenth<0)
		return -1;	

	//freetype
	freetype.filename	= FONTFILE; 
//	freetype.angle		= (0.0 / 360 ) * 3.14159 * 2;
	
	freetype.error = FT_Init_FreeType(&freetype.library);
	/* error handling omitted */
	
	freetype.error = FT_New_Face( freetype.library, freetype.filename, 0, &freetype.face );
	/* error handling omitted */
	
	/* use 50pt at 100dpi */
	FT_Set_Pixel_Sizes( freetype.face, fontSize, 0);
	  
	/* cmap selection omitted;										  */
	/* for simplicity we assume that the font contains a Unicode cmap */
	freetype.slot = freetype.face->glyph;
	
	/* set up matrix */
//	freetype.matrix.xx = (FT_Fixed)( cos( freetype.angle ) * 0x10000L );
//	freetype.matrix.xy = (FT_Fixed)(-sin( freetype.angle ) * 0x10000L );
//	freetype.matrix.yx = (FT_Fixed)( sin( freetype.angle ) * 0x10000L );
//	freetype.matrix.yy = (FT_Fixed)( cos( freetype.angle ) * 0x10000L );
	
	freetype.pen.x = x* 64;
	freetype.pen.y = (LCDHEIGHT-y-fontSize) * 64;

	if(showLenth < lenth)
		lenth = showLenth;		
	
	for ( int n = 0; n < lenth; n++ )
	{
		/* set transformation */
//		FT_Set_Transform( freetype.face, &freetype.matrix, &freetype.pen );
		FT_Set_Transform(freetype.face, 0, &freetype.pen);
	
		/* load glyph image into the slot (erase previous one) */
		freetype.error = FT_Load_Char(freetype.face, code[n], FT_LOAD_RENDER);
		if (freetype.error)
		{
//			printf("FT_LOAD_Char error\r\n");
			continue;				  /* ignore errors */
		}
	
		/* now, draw to our target surface (convert position) */
		draw_bitmap( &freetype.slot->bitmap, freetype.slot->bitmap_left, LCDHEIGHT- freetype.slot->bitmap_top ,frontcolor, backcolor);
	
		/* increment pen position */
		freetype.pen.x += freetype.slot->advance.x;
		freetype.pen.y += freetype.slot->advance.y;
	}

	FT_Done_Face	( freetype.face );
	FT_Done_FreeType( freetype.library );
	 
	return 0;
}

